Skip to content

Conversation

@mnocon
Copy link
Contributor

@mnocon mnocon commented Jan 21, 2026

Doc for https://ibexa.atlassian.net/browse/IBX-10630

Turns out we didn't have virtual products mentioned at all in the doc, so I'm adding a mention to the product guide.

Code tested locally:

Screenshot 2026-01-22 at 09 44 18

@mnocon mnocon changed the base branch from 5.0 to 4.6 January 22, 2026 08:42
@mnocon mnocon changed the title product type nam Described virtual products and added an example creating product type with PHP API Jan 22, 2026
@mnocon mnocon marked this pull request as ready for review January 22, 2026 09:25
@github-actions
Copy link

Preview of modified files

Preview of modified Markdown:


$marketingDescriptionFieldDefinition = $this->contentTypeService->newFieldDefinitionCreateStruct(
'marketing_description',
'ezstring'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: on upmerge, this should be ibexa_string

@mnocon mnocon requested a review from a team January 22, 2026 12:51
@ibexa-workflow-automation-1 ibexa-workflow-automation-1 bot requested review from adriendupuis, dabrt and julitafalcondusza and removed request for a team January 22, 2026 12:51
@adriendupuis adriendupuis self-requested a review January 27, 2026 12:45
mnocon and others added 2 commits January 27, 2026 13:47
Co-authored-by: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com>
@github-actions
Copy link

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/api/product_catalog/src/Command/ProductTypeCommand.php


code_samples/api/product_catalog/src/Command/ProductTypeCommand.php

docs/pim/product_api.md@110:``` php
docs/pim/product_api.md@111:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 43, 44) =]]
docs/pim/product_api.md@112:```
docs/pim/product_api.md@114:``` php
docs/pim/product_api.md@115:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 62, 66) =]]
docs/pim/product_api.md@116:```

001⫶ $productTypeCreateStruct = $this->localProductTypeService->newProductTypeCreateStruct(
002⫶ 'digital_product',
003⫶ 'eng-GB'
004⫶ );

docs/pim/product_api.md@120:``` php
docs/pim/product_api.md@121:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 67, 71) =]]
docs/pim/product_api.md@122:```

001⫶ $productTypeCreateStruct->setNames([
002⫶ 'eng-GB' => 'Digital Product',
003⫶ 'pol-PL' => 'Produkt Cyfrowy',
004⫶ ]);

docs/pim/product_api.md@126:``` php
docs/pim/product_api.md@127:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 72, 73) =]]
docs/pim/product_api.md@128:```

001⫶ $productTypeCreateStruct->setVirtual(true);

docs/pim/product_api.md@135:``` php
docs/pim/product_api.md@136:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 76, 83) =]]
docs/pim/product_api.md@137:```

001⫶ $marketingDescriptionFieldDefinition = $this->contentTypeService->newFieldDefinitionCreateStruct(
002⫶ 'marketing_description',
003⫶ 'ezstring'
004⫶ );
005⫶ $marketingDescriptionFieldDefinition->names = ['eng-GB' => 'Marketing Description'];
006⫶ $marketingDescriptionFieldDefinition->position = 100;
007⫶ $contentTypeCreateStruct->addFieldDefinition($marketingDescriptionFieldDefinition);

docs/pim/product_api.md@145:``` php
docs/pim/product_api.md@146:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 84, 85) =]]
docs/pim/product_api.md@147:```

001⫶ $sizeAttribute = $this->attributeDefinitionService->getAttributeDefinition('size');

docs/pim/product_api.md@151:``` php
docs/pim/product_api.md@152:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 86, 93) =]]
docs/pim/product_api.md@153:```

001⫶ $attributeAssignment = new AssignAttributeDefinitionStruct(
002⫶ $sizeAttribute,
003⫶ false,
004⫶ false
005⫶ );
006⫶
007⫶ $productTypeCreateStruct->setAssignedAttributesDefinitions([$attributeAssignment]);

docs/pim/product_api.md@159:``` php
docs/pim/product_api.md@160:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 94, 95) =]]
docs/pim/product_api.md@161:```

001⫶ $newProductType = $this->localProductTypeService->createProductType($productTypeCreateStruct);

docs/pim/product_api.md@167:``` php
docs/pim/product_api.md@168:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 96, 97) =]]
docs/pim/product_api.md@169:```

001⫶ $productType = $this->productTypeService->getProductType($productTypeIdentifier);


001⫶ $productType = $this->productTypeService->getProductType($productTypeIdentifier);

docs/pim/product_api.md@116:``` php
docs/pim/product_api.md@117:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 47, 52) =]]
docs/pim/product_api.md@118:```
docs/pim/product_api.md@173:``` php
docs/pim/product_api.md@174:[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 100, 105) =]]
docs/pim/product_api.md@175:```

001⫶ $productTypes = $this->productTypeService->findProductTypes();
002⫶
003⫶ foreach ($productTypes as $productType) {
004⫶ $output->writeln($productType->getName() . ' with identifier ' . $productType->getIdentifier());
005⫶ }


001⫶ $productTypes = $this->productTypeService->findProductTypes();
002⫶
003⫶ foreach ($productTypes as $productType) {
004⫶ $output->writeln($productType->getName() . ' with identifier ' . $productType->getIdentifier());
005⫶ }

Download colorized diff

Copy link
Contributor

@adriendupuis adriendupuis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't straiten developers to virtual as being only digital.

Product types in [[= product_name =]] can be either virtual or physical:

- **Physical products** are tangible items that require shipping (for example: books, clothing, electronics).
- **Virtual products** are digital items that don't require physical delivery (for example: software licenses, e-books, online courses, digital downloads).
Copy link
Contributor

@adriendupuis adriendupuis Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree with "digital" here. There are some examples that are at the edge, nothing is shipped this time but could have been already shipped ("subscription renewal" of a GPS device, of an e-reader device, internet box TV programs, …), or it can become physical when needed ("Additional X years insurance or warranty" with product replacement or loan of the similar product during the repairs, …), it can be a virtual tokken giving access to physical product ("spectacle ticket", "virtual gift card" for recipient to buy real products,…). Let's not focus on "digital" and see usages that can be invented.

Suggested change
- **Virtual products** are digital items that don't require physical delivery (for example: software licenses, e-books, online courses, digital downloads).
- **Virtual products** are items that don't require physical delivery (for example: software licenses, e-books, online courses, digital downloads, additional warranty, tickets for an event).

(No issue in the fact that the example is a digital product.)

Comment on lines +89 to +90
This product type property affects the checkout process.
Virtual products skip the [shipping step](shipping_management.md) during checkout.
Copy link
Contributor

@adriendupuis adriendupuis Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would avoid confusion here, their presence doesn't "force skip".

Suggested change
This product type property affects the checkout process.
Virtual products skip the [shipping step](shipping_management.md) during checkout.
This product type property can affect the checkout process.
A cart of only virtual products skips the [shipping step](shipping_management.md) during checkout.

[[= include_file('code_samples/api/product_catalog/src/Command/ProductTypeCommand.php', 67, 71) =]]
```

To create a virtual product type (for digital products that don't require shipping), use `setVirtual()`:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To create a virtual product type (for digital products that don't require shipping), use `setVirtual()`:
To create a virtual product type (for products that don't require shipping), use `setVirtual()`:

Comment on lines +155 to +157
For more information about working with attributes through PHP API, see [Attributes](#attributes).

Finally, create the product type with `LocalProductTypeServiceInterface::createProductType()`:
Copy link
Contributor

@adriendupuis adriendupuis Jan 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this not part of "Assigning attributes" section, I would add a new heading:

Suggested change
For more information about working with attributes through PHP API, see [Attributes](#attributes).
Finally, create the product type with `LocalProductTypeServiceInterface::createProductType()`:
For more information about working with attributes through PHP API, see [Attributes](#attributes).
#### Storing new product type
Finally, create the product type with `LocalProductTypeServiceInterface::createProductType()`:


To assign product attributes to the product type, use `setAssignedAttributesDefinitions()` with an array of [`AssignAttributeDefinitionStruct`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-Local-Values-ProductType-AssignAttributeDefinitionStruct.html) objects.

First, retrieve the attribute definition using [`AttributeDefinitionServiceInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-AttributeDefinitionServiceInterface.html):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
First, retrieve the attribute definition using [`AttributeDefinitionServiceInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-AttributeDefinitionServiceInterface.html):
First, retrieve the attribute definition by using [`AttributeDefinitionServiceInterface`](/api/php_api/php_api_reference/classes/Ibexa-Contracts-ProductCatalog-AttributeDefinitionServiceInterface.html):

"using" alone could be interpreted as "that uses"
Instead of "by using" you could use "with"

@dabrt
Copy link
Contributor

dabrt commented Jan 27, 2026

I would add a link somewhere that binds dev doc with user doc by pointing to:
https://doc.ibexa.co/projects/userguide/en/latest/pim/create_virtual_product/

@adriendupuis
Copy link
Contributor

I would add a link somewhere that binds dev doc with user doc by pointing to: https://doc.ibexa.co/projects/userguide/en/latest/pim/create_virtual_product/

@mnocon And I discover that the user doc doesn't have the "digital" bias and even quotes examples I was thinking of. 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants